<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Creating a captcha in a Servlet</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="jee tutorial, Java, web applications, Java Servlets, Captcha">
<meta name="description" content="In this part of the Java EE 5 tutorial, we create a captcha in a Servlet.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>


<div class="content">


<a href="/" title="Home">Home</a>&nbsp;
<a href=".." title="Contents">Contents</a>



<h1>Creating a captcha in a Servlet</h1>

<p>
In this part of the JEE tutorials we will use a captcha test in our form.
</p>

<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div> 

<p>
A <b>captcha</b> is a type of challenge-response test used in computing to determine 
whether the user is human. Captcha is a contrived acronym for "Completely Automated 
Public Turing test to tell Computers and Humans Apart". (Wikipedia)
Using captchas on Internet is almost inevitable, because the forums and message boards 
are infested with spam.
</p>


<h2>Captcha</h2>

<p>
In the following example, we will demonstrate a captcha system in a small 
example. We have a html form. At the bottom of the form, we have a input 
tag named code. Here the user has to copy the characters of an image, which 
is displayed below the input box. This is the most common captcha system 
on the Internet. The main part of the captcha system is 
a image, displaying random alphanumeric characters. The characters are usually 
blurred or otherwise made a bit more
difficult to read.
</p>

<div class="codehead">style.css</div>
<pre class="code">
* { font-size: 12px; font-family: Verdana }

input, textarea { border: 1px solid #ccc }

tr { margin: 5px; padding:5px;}

.alert { font-size:15px; color:red; font-weight:bolder }
</pre>

<p>
This is a simple stylesheet for our example. The .alert class is used to 
format text displaying whether 
we passed the test or not.
</p>

<div class="codehead">index.jsp</div>
<pre class="code">
&lt;%@page contentType="text/html" pageEncoding="UTF-8"%&gt;

&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;
&lt;title&gt;Captcha&lt;/title&gt;
&lt;link rel="stylesheet" href="style.css"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;center&gt;
&lt;form method="post"&gt;
&lt;table cellspacing="15"&gt;
&lt;tr&gt;
&lt;td&gt;Name&lt;/td&gt;
&lt;td&gt;&lt;input type="text" name="name"&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Message&lt;/td&gt;
&lt;td&gt; &lt;textarea type="text" cols="25" rows="8" name="message"&gt;&lt;/textarea&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;Are you human?&lt;/td&gt;
&lt;td&gt;&lt;input type="text" name="code"&gt;&lt;/td&gt;
&lt;/tr&gt;

&lt;/table&gt;

&lt;br&gt;
&lt;img src="http://localhost:8080/captcha/CaptchaServlet"&gt; 

&lt;br&gt;&lt;br&gt;
&lt;input type="submit" value="submit"&gt;

&lt;/form&gt;
&lt;br&gt;&lt;br&gt;
&lt;%
  String captcha = (String) session.getAttribute("captcha");
  String code = (String) request.getParameter("code");

  if (captcha != null &amp;&amp; code != null) {

    if (captcha.equals(code)) {
	  out.print("&lt;p class='alert'&gt;Correct&lt;/p&gt;");
    } else {
          out.print("&lt;p class='alert'&gt;Incorrect&lt;/p&gt;");
    }
  }
%&gt;
&lt;/center&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>

<p>
This is the file, where we define the html form, load the captcha image 
and react to submit action.
</p>

<pre class="explanation">
&lt;form method="post"&gt;
</pre>

<p>
If we don't provide the action parameter, the processing is transfered to the 
same file by default. e.g index.jsp 
in our case.
</p>

<pre class="explanation">
&lt;img src="http://localhost:8080/captcha/CaptchaServlet"&gt; 
</pre>

<p>
This is the way, how we get the image from the servlet. We provide the location 
of the servlet to the src parameter
of the html img tag. Each time we refresh the page, we get a new image from 
the <b class="keyword">CaptchaServlet</b>.
</p>

<pre class="explanation">
String captcha = (String) session.getAttribute("captcha");
String code = (String) request.getParameter("code");

if (captcha != null &amp;&amp; code != null) {

if (captcha.equals(code)) {
        out.print("&lt;p class='alert'&gt;Correct&lt;/p&gt;");
} else {
        out.print("&lt;p class='alert'&gt;Incorrect&lt;/p&gt;");
}
}
</pre>

<p>
This code receives the parameters from the request. The message and name 
parameters are ignored. 
The captcha is a string, that is set randomly by the servlet. This string 
is being shown in the image.
The code is the text, which is put by the user. If these two strings match, 
we output "Correct" string, otherwise "Incorrect".
</p>

<img src="/img/java/jee/captcha.png" alt="Captcha">
<div class="figure">Figure: Captcha</div>


<div class="codehead">CaptchaServlet.java</div>
<pre class="code">
package com.zetcode;

import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.*;

import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.*;
import javax.servlet.http.*;


public class CaptchaServlet extends HttpServlet {


  protected void processRequest(HttpServletRequest request, 
                                HttpServletResponse response) 
                 throws ServletException, IOException {

    int width = 150;
    int height = 50;

    char data[][] = {
        { 'z', 'e', 't', 'c', 'o', 'd', 'e' },
        { 'l', 'i', 'n', 'u', 'x' },
        { 'f', 'r', 'e', 'e', 'b', 's', 'd' },
        { 'u', 'b', 'u', 'n', 't', 'u' },
        { 'j', 'e', 'e' }
    };


    BufferedImage bufferedImage = new BufferedImage(width, height, 
                  BufferedImage.TYPE_INT_RGB);

    Graphics2D g2d = bufferedImage.createGraphics();

    Font font = new Font("Georgia", Font.BOLD, 18);
    g2d.setFont(font);

    RenderingHints rh = new RenderingHints(
           RenderingHints.KEY_ANTIALIASING,
           RenderingHints.VALUE_ANTIALIAS_ON);

    rh.put(RenderingHints.KEY_RENDERING, 
           RenderingHints.VALUE_RENDER_QUALITY);

    g2d.setRenderingHints(rh);

    GradientPaint gp = new GradientPaint(0, 0, 
    Color.red, 0, height/2, Color.black, true);

    g2d.setPaint(gp);
    g2d.fillRect(0, 0, width, height);

    g2d.setColor(new Color(255, 153, 0));

    Random r = new Random();
    int index = Math.abs(r.nextInt()) % 5;

    String captcha = String.copyValueOf(data[index]);
    request.getSession().setAttribute("captcha", captcha );

    int x = 0; 
    int y = 0;

    for (int i=0; i&lt;data[index].length; i++) {
        x += 10 + (Math.abs(r.nextInt()) % 15);
        y = 20 + Math.abs(r.nextInt()) % 20;
        g2d.drawChars(data[index], i, 1, x, y);
    }

    g2d.dispose();

    response.setContentType("image/png");
    OutputStream os = response.getOutputStream();
    ImageIO.write(bufferedImage, "png", os);
    os.close();
  } 


  protected void doGet(HttpServletRequest request, 
                       HttpServletResponse response)
                           throws ServletException, IOException {
      processRequest(request, response);
  } 


  protected void doPost(HttpServletRequest request, 
                        HttpServletResponse response)
                            throws ServletException, IOException {
      processRequest(request, response);
  }
}
</pre>

<p>
In the Captcha servlet, we create an image of 150*50 size. To create the 
image, we use the Java 2D vector library. The image is filled with red - 
black gradient. We draw randomly a string into the image.
</p>

<pre class="explanation">
char data[][] = {
    { 'z', 'e', 't', 'c', 'o', 'd', 'e' },
    { 'l', 'i', 'n', 'u', 'x' },
    { 'f', 'r', 'e', 'e', 'b', 's', 'd' },
    { 'u', 'b', 'u', 'n', 't', 'u' },
    { 'j', 'e', 'e' }
};
</pre>

<p>
This is an array, from which we choose our string.
</p>

<pre class="explanation">
BufferedImage bufferedImage = new BufferedImage(width, height, 
            BufferedImage.TYPE_INT_RGB);

Graphics2D g2d = bufferedImage.createGraphics();
</pre>

<p>
We will draw into a buffered image. 
</p>

<pre class="explanation">
RenderingHints rh = new RenderingHints(
        RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);

rh.put(RenderingHints.KEY_RENDERING, 
        RenderingHints.VALUE_RENDER_QUALITY);

g2d.setRenderingHints(rh);
</pre>

<p>
The rendering hints are used to increase the quality of the text.
</p>

<pre class="explanation">
g2d.setRenderingHints(rh);

GradientPaint gp = new GradientPaint(0, 0, 
Color.red, 0, height/2, Color.black, true);

g2d.setPaint(gp);
g2d.fillRect(0, 0, width, height);
</pre>

<p>
Here we draw the gradient.
</p>

<pre class="explanation">
Random r = new Random();
int index = Math.abs(r.nextInt()) % 5;

String captcha = String.copyValueOf(data[index]);
request.getSession().setAttribute("captcha", captcha );
</pre>

<p>
Here we randomly choose an index into the array. We also set the chosen string into the
session, so that we can compare it later to the parameter, specified by the user.
</p>

<pre class="explanation">
int x = 0; 
int y = 0;

for (int i=0; i&lt;data[index].length; i++) {
    x += 10 + (Math.abs(r.nextInt()) % 15);
    y = 20 + Math.abs(r.nextInt()) % 20;
    g2d.drawChars(data[index], i, 1, x, y);
}
</pre>

<p>
This is the code, that draws the string into the image. We must make sure, 
that the text fits into the boudaries of the image.
</p>

<pre class="explanation">
response.setContentType("image/png");
OutputStream os = response.getOutputStream();
ImageIO.write(bufferedImage, "png", os);
os.close();
</pre>

<p>
Finally, we return the image through a byte stream. We set a content type 
to png image. The <code>write()</code> method of the ImageIO class 
writes the data from the buffered image into the servlet output stream. 
This way we send binary data to the client.
</p>

<p>
In this chapter we have created a captcha in a Java Servlet. 
</p>

<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div> 
<br> 


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified January 27, 2007  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>
